--This 2d3d browser don't use the chrome module and mouse and keyboard inputs are not working in this one.
include("shared.lua");
--######################################
-- HTML-Panel which fixes the scrollbars by clipping them
--######################################

-- The default image/HTML stuff to show
local AJAX_LOADER_IMG = "http://www.ajaxload.info/cache/FF/FF/FF/00/00/00/35-0.gif";
local AJAX_LOADER_IMG_DIMENSIONS = {66,66};
local AJAX_LOADER = 
[[
<html>
	<head>
		<style type="text/css">
			body, html{
				padding:0px 0px 0px 0px;
				margin:0px 0px 0px 0px;
				text-align: center;
				vertical-align:50%;
				height:100%;
			}
			img{
				width:]]..AJAX_LOADER_IMG_DIMENSIONS[1]..[[;
				heigth:]]..AJAX_LOADER_IMG_DIMENSIONS[2]..[[;
				position:relative; /*allows for top property to move the element*/
				top:50%; /*moves it 50% of #container's height down the page*/
				margin-top:-]]..(AJAX_LOADER_IMG_DIMENSIONS[2]/2)..[[px; /*pulls it back up by half it's height*/
			}
		</style>
	</head>
	<body scroll="no">
		<img src="]]..AJAX_LOADER_IMG..[[" />
	</body>
</html>
]]

local PANEL = {};
AccessorFunc(PANEL,"b_AllowScrollbars","ScrollBars",FORCE_BOOL);
AccessorFunc(PANEL,"b_Animated","Animated",FORCE_BOOL);

--################### Init@aVoN
function PANEL:Init()
	self.HTML = vgui.Create("HTML",self);
	self.HTML:NoClipping(false);
	self.HTML:SetPaintBorderEnabled(false);
	self.HTML:SetPaintBackgroundEnabled(true);
	self:SetScrollBars(true);
	self:SetKeyBoardInputEnabled(true)
	self:SetMouseInputEnabled(true)

end

--################### Perform Layout @aVoN
function PANEL:PerformLayout()
	local w,h = self:GetSize();
	if(self.b_Loading) then
		-- Shrink the HTML panel to the animation-image size, center it and activate the animation-mode. The reason why we shrink it is animation-mode sucks as more fps as bigger it is.
		-- We need to calc a new heigth and width according to the power of 2. Otherwise we get pink/black checkboard shit
		local wide = 2^(math.ceil(math.log(AJAX_LOADER_IMG_DIMENSIONS[1])/math.log(2)));
		local tall = 2^(math.ceil(math.log(AJAX_LOADER_IMG_DIMENSIONS[2])/math.log(2)));
		self.HTML:SetPos((w - wide)/2,(h - tall)/2);
		self.HTML:SetSize(wide + 1,tall + 1);
	else
		self.HTML:SetPos(-1,-1); -- -1 to avoid borders
		self.HTML:SetSize(w + 3,h + 3); -- + 3 because I disabled SetPaintBorderEnabled which makes the panel smaller
	end
end

--################### Make it UPDATE/Animated @aVoN
function PANEL:Think()
	if(not (self.b_Animated or self.b_Loading)) then return end;
	self:Animate(true);
end

--################### Manually animated @aVoN
-- Note: Override is used internally, to prevent the function below getting called two times (external and internal)
function PANEL:Animate(override)
	if((self.b_Loading or self.b_Animated) and not override) then return end;
	-- This is REALLY really FPS expensive!
	local h = self.HTML:GetTall();
	self.HTML:SetTall(h - 1);
	self.HTML:SetTall(h);
end

--################### Paint @aVoN
function PANEL:Paint()
	if(not self.b_Loading) then return end;
	surface.SetDrawColor(255,255,255,255);
	surface.DrawRect(0,0,self:GetSize());
end

--################### Mark this panel as loading @aVoN
function PANEL:SetLoading(b)
	if(b) then self:SetHTML(AJAX_LOADER) end;
	self.b_Loading = b;
	self:PerformLayout();
end

-- Relay all inputs to this NewHTML to the original HTML panel
for _,v in pairs({"SetHTML","Refresh","Clear","Stop"}) do
	PANEL[v] = function(self,...)
		self.HTML[v](self.HTML,...);
	end
end

--################### Instead of opening the URL we use SetHTML and an inlinefram -> Fixes bugs with ugly scrollbars@aVoN
function PANEL:OpenURL(url)
	local scrollbars = 'scrolling="no"';
	if(self.b_AllowScrollbars) then scrollbars = 'scrolling="yes"' end;
	self:SetLoading(false); -- We aren't loading anymore
	self:SetScrollBars(true);
	self:SetKeyBoardInputEnabled(true)
	self:SetMouseInputEnabled(true)
	self.HTML:SetHTML(
	[[
	<html>
		<head>
			<style type="text/css">
				body{
					padding:0px 0px 0px 0px;
					margin:0px 0px 0px 0px;
				}
			</style>
		</head>
		<body scroll="no">
		   <iframe src="]]..url..[["
			height="100%" width="100%" frameborder="0" ]]..scrollbars..[[/>
		</body>
	</html>
	]]
	);
end

vgui.Register("NewHTML",PANEL,"Panel");

--######################################
-- SENT which draws a HTML-Panels in 3D
--######################################

--################### Create the HTML Panel we want to draw on @aVoN
function ENT:CreatePanel()
	local panel = vgui.Create("NewHTML");
	if(not IsValid(panel)) then return end;
	panel:SetScrollBars(true);
	panel:SetLoading(true);
	panel:SetSize(0,0);
	panel:SetScrollBars(true);
	panel:SetKeyBoardInputEnabled( true )
	panel:SetMouseInputEnabled( true )
	return panel;
end

--################### Panel created successfully @aVoN
function ENT:OnPanelCreated(panel)
	if(self.Data) then
		panel:OpenURL(self.Data[1]);
		self:SetSizes(panel,self.Data[2],self.Data[3],self.Data[4]);
	else
		RunConsoleCommand("__AdvertGetData",self.Entity:EntIndex()); -- Tell server to send us data about what to draw
	end
end

--################### Animation-Mode? @aVoN
function ENT:PrePanelDraw(panel,w,h)
	if(self.Data and self.Data[5]) then
		panel:Animate();
	end
end

--################### Draws an overlay @aVoN
local overlay = surface.GetTextureID("Decals/light");
function ENT:PostPanelDraw(panel,w,h)
	if(self.Data and not self.Data[6]) then
		surface.SetDrawColor(0,0,0,60);
		surface.DrawRect(0,0,w,h);
		surface.SetTexture(overlay);
		surface.DrawTexturedRect(0,0,w,h);
	end
end

--################### Set size of the panel @aVoN
function ENT:SetSizes(panel,w,h,r)
	self:SetSize(w,h); -- Set the size of the 3D world panel
	self:SetResolution(r);
	panel:SetSize(w*r,h*r); -- Set the size of the 2D panel we draw on the 3D Panel
end

--################### Receive data @aVoN
local NextLoad = 0;

function ENT.__ReceiveData(data)
	local self = data:ReadEntity();
	if(not ValidEntity(self.Entity)) then return end;
	local panel = self:GetPanel();
	local data = {
		data:ReadString(), -- Url
		data:ReadShort(), -- Width
		data:ReadShort(), -- Height
		data:ReadFloat(), -- Resolution
		data:ReadBool(), -- Animation Mode?
		data:ReadBool(), -- Overlay
	}
	if(not self.Data) then -- First Load: Show a loading animation
		self.Data = data;
		self:SetSizes(panel,data[2],data[3],data[4]);
		local time = CurTime();
		local add = math.Clamp(NextLoad - time,0,1000);
		NextLoad = time + add + 0.1; -- We NEED a tiny delay of at least 0.1 seconds between two or more panels to load. Otherwise we get an issue where two panels (loaded at once) show the same content
		timer.Simple(2 + add,self.LoadURLDelayed,self);
		return;
	end
	-- Url changed
	if(data[1] ~= self.Data[1]) then
		panel:OpenURL(data[1]);
	end
	-- Any sizes changed
	local changed = false;
	if(data[2] ~= self.Data[2] or data[3] ~= self.Data[3] or data[4] ~= self.Data[4]) then
		self:SetSizes(panel,data[2],data[3],data[4]);
	end
	self.Data = data;
end
usermessage.Hook("AdvertData",ENT.__ReceiveData);

--################### Sets the URL, but delayed @aVoN
function ENT:LoadURLDelayed(url)
	if(not IsValid(self)) then return end;
	local panel = self:GetPanel();
	if(not IsValid(panel)) then return end;
	panel:OpenURL(self.Data[1]);
end